package com.todo.pro.controller;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.todo.pro.entity.Plan;
import com.todo.pro.entity.PlanLabel;
import com.todo.pro.entity.PlanPicture;
import com.todo.pro.entity.User;
import com.todo.pro.enums.PlanStatusEnum;
import com.todo.pro.req.model.FinishRateModel;
import com.todo.pro.req.model.PlanModel;
import com.todo.pro.service.PlanLabelService;
import com.todo.pro.service.PlanPictureService;
import com.todo.pro.service.PlanService;
import com.todo.pro.service.UserService;
import com.todo.pro.util.AesUtil;
import com.todo.pro.util.EmojiUtils;
import com.todo.pro.web.domain.AjaxResult;
import com.xiaoleilu.hutool.date.DateUtil;
import com.xiaoleilu.hutool.util.NumberUtil;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author SiZhongxia
 * @since 2017-12-27
 */
@Controller
@RequestMapping("/plan")
public class PlanController {

	@Autowired
	private UserService userService;
	@Autowired
	private PlanService planService;
	@Autowired
	private PlanLabelService planLabelService;
	@Autowired
	private PlanPictureService planPictureService;

	private final String DATE_FORMAT = "yyyy-MM-dd HH:mm";

	@SuppressWarnings({ "unchecked", "unlikely-arg-type" })
	@ResponseBody
	@RequestMapping(value = { "/data" })
	public AjaxResult data(@RequestBody(required = true) PlanModel requestModel) {
		String token = requestModel.getToken();
		if (StringUtils.isBlank(token)) {
			return AjaxResult.error("请求失败，无效的数据 E1");
		}

		String userId = AesUtil.decryptStr(token);
		if (userId == null) {
			return AjaxResult.error("请求失败，无效的数据 E3");
		}

		User user = userService.selectById(new Long(userId));
		if (user == null) {
			return AjaxResult.error("请求失败，无效的数据 E4");
		}

		Integer page = requestModel.getPage();
		if (page == null || page.intValue() < 1) {
			page = 1;
		}

		Wrapper<Plan> planWrapper = new EntityWrapper<>();

		String status = requestModel.getStatus();
		if (StringUtils.isNotBlank(status)) {
			planWrapper.eq("plan_status", status);
		}
		String planName = requestModel.getPlanName();
		if (StringUtils.isNotBlank(planName)) {
			planWrapper.like("plan_name", planName);
		}
		planWrapper.eq("user_id", user.getId()).orderBy("create_time", false);

		Page<Plan> pageInfo = PageHelper.startPage(page, 10, true);
		List<Plan> plans = planService.selectList(planWrapper);

		List<Map<String, Object>> list = new ArrayList<>();
		if (plans != null && plans.size() > 0) {
			List<Long> planIds = new ArrayList<>();
			Map<String, Object> item = null;
			for (Plan plan : plans) {
				item = new HashMap<>();
				item.put("id", plan.getId().toString());
				item.put("planName", EmojiUtils.parseToUnicode(plan.getPlanName()));
				item.put("planContent", EmojiUtils.parseToUnicode(plan.getPlanContent()));

				Date finishPlanTime = plan.getPlanFinishTime();
				if (PlanStatusEnum.isHaveInHand(plan.getPlanStatus())
						&& System.currentTimeMillis() > finishPlanTime.getTime()) {
					item.put("overdue", true);
					item.put("planStatus", "已过期");

					if (!plan.getPlanStatus().equals(PlanStatusEnum.Delay.name())) {
						plan.setPlanStatus(PlanStatusEnum.Delay.name());
						planService.updateById(plan);
					}

				} else {
					item.put("overdue", PlanStatusEnum.isDelay(plan.getPlanStatus()));
					item.put("planStatus", PlanStatusEnum.getStatusNameByCode(plan.getPlanStatus()));
				}
				// 进度
				item.put("planSpeed", plan.getPlanSpeed());
				item.put("labels", new HashSet<>());
				item.put("hasPicture", plan.getHasPicture() == 1);
				item.put("createTime", DateUtil.format(plan.getCreateTime(), DATE_FORMAT));
				list.add(item);

				planIds.add(plan.getId());
			}

			Wrapper<PlanLabel> planLabelWrapper = new EntityWrapper<>();
			planLabelWrapper.in("plan_id", planIds);
			List<PlanLabel> labels = planLabelService.selectList(planLabelWrapper);
			for (PlanLabel label : labels) {
				for (Map<String, Object> pi : list) {
					if (pi.get("id").equals(label.getId().toString())) {
						((Set<String>) pi.get(labels)).add(EmojiUtils.parseToUnicode(label.getLabelName()));
					}
				}
			}
		}

		return AjaxResult.success().put("total", pageInfo.getTotal()).put("hasNext", pageInfo.getPages() > page)
				.put("pages", pageInfo.getPages()).put("list", list);
	}

	@ResponseBody
	@RequestMapping(value = { "/create" })
	public AjaxResult create(@RequestBody(required = true) PlanModel requestModel) {
		String token = requestModel.getToken();
		if (StringUtils.isBlank(token)) {
			return AjaxResult.error("请求失败，无效的数据 E1");
		}

		String userId = AesUtil.decryptStr(token);
		if (userId == null) {
			return AjaxResult.error("请求失败，无效的数据 E3");
		}

		User user = userService.selectById(new Long(userId));
		if (user == null) {
			return AjaxResult.error("请求失败，无效的数据 E4");
		}
		String[] planPictures = requestModel.getPlanPictures();
		int hasPic = 0;
		if (planPictures != null && planPictures.length > 0) {
			hasPic = 1;
		}

		Plan plan = new Plan();
		plan.setUserId(user.getId());
		plan.setPlanName(EmojiUtils.parseToAliases(requestModel.getPlanName()));
		plan.setPlanContent(EmojiUtils.parseToAliases(requestModel.getPlanContent()));
		plan.setPlanFinishTime(DateUtil.parse(requestModel.getPlanFinishTime()));
		plan.setNextRemindTime(DateUtil.parse(requestModel.getNextRemindTime()));
		plan.setHasPicture(hasPic);
		plan.setPlanStatus(PlanStatusEnum.HaveInHand.name());
		plan.setPlanSpeed(0);
		plan.setCreateTime(DateUtil.date());

		planService.insert(plan);

		if (hasPic > 0) {
			List<PlanPicture> pps = new ArrayList<>();
			PlanPicture ppItem = null;
			for (String picUrl : planPictures) {
				ppItem = new PlanPicture();
				ppItem.setPlanId(plan.getId());
				ppItem.setPicUrl(picUrl);
				ppItem.setUserId(user.getId());
				pps.add(ppItem);
			}
			planPictureService.insertBatch(pps);
		}

		String planLabels = requestModel.getPlanLabels();
		if (StringUtils.isNotBlank(planLabels)) {

			List<PlanLabel> pls = new ArrayList<>();
			PlanLabel pl = null;
			for (String label : planLabels.split("[,;，；]")) {
				label = EmojiUtils.parseToAliases(label);
				if (StringUtils.isBlank(label)) {
					continue;
				}
				pl = new PlanLabel();
				pl.setPlanId(plan.getId());
				pl.setLabelName(label);
				pl.setUserId(user.getId());
				pls.add(pl);
			}

			if (pls.size() > 0) {
				planLabelService.insertBatch(pls);
			}
		}

		return AjaxResult.success().put("planId", plan.getId());
	}

	@ResponseBody
	@RequestMapping(value = { "/finishRate" })
	public AjaxResult finishRate(@RequestBody(required = true) FinishRateModel requestModel) {

		String token = requestModel.getToken();
		if (StringUtils.isBlank(token)) {
			return AjaxResult.error("请求失败，无效的数据 E1");
		}

		String userId = AesUtil.decryptStr(token);
		if (userId == null) {
			return AjaxResult.error("请求失败，无效的数据 E3");
		}

		User user = userService.selectById(new Long(userId));
		if (user == null) {
			return AjaxResult.error("请求失败，无效的数据 E4");
		}

		return AjaxResult.success().put("finishRate", new DecimalFormat("#.00").format(user.getFinishRate()));
	}

	@ResponseBody
	@RequestMapping(value = { "/detail" })
	public AjaxResult detail(@RequestBody(required = true) PlanModel requestModel) {
		String token = requestModel.getToken();
		if (StringUtils.isBlank(token)) {
			return AjaxResult.error("请求失败，无效的数据 E1");
		}

		String userId = AesUtil.decryptStr(token);
		if (userId == null) {
			return AjaxResult.error("请求失败，无效的数据 E3");
		}

		User user = userService.selectById(new Long(userId));
		if (user == null) {
			return AjaxResult.error("请求失败，无效的数据 E4");
		}

		String planId = requestModel.getPlanId();
		if (StringUtils.isBlank(planId)) {
			return AjaxResult.error("请求失败，无效的数据 E5");
		}

		Plan plan = planService.selectById(planId);
		if (plan == null) {
			return AjaxResult.error("请求失败，无效的数据 E6");
		}

		requestModel.setPlanName(plan.getPlanName());
		requestModel.setPlanContent(plan.getPlanContent());
		requestModel.setStatus(PlanStatusEnum.getStatusNameByCode(plan.getPlanStatus()));
		requestModel.setPlanSpeed(plan.getPlanSpeed().toString());
		Date cancleTime = plan.getCancleTime();
		Date createTime = plan.getCreateTime();
		Date planFinishTime = plan.getPlanFinishTime();
		Date finishTime = plan.getFinishTime();
		Long useTime = plan.getUseTime();

		requestModel.setCreateTime(DateUtil.format(createTime, DATE_FORMAT));
		requestModel.setPlanFinishTime(DateUtil.format(planFinishTime, DATE_FORMAT));

		if (finishTime != null) {
			requestModel.setFinishTime(DateUtil.format(finishTime, DATE_FORMAT));
		} else {
			requestModel.setFinishTime("");
		}

		if (cancleTime != null) {
			requestModel.setCancleTime(DateUtil.format(cancleTime, DATE_FORMAT));
		} else {
			requestModel.setCancleTime("");
		}

		if (useTime != null) {
			requestModel.setUseTime(useTime.longValue() / 1000 + "秒");
		} else {
			requestModel.setUseTime("");
		}

		requestModel.setCanHandle(
				PlanStatusEnum.isHaveInHand(plan.getPlanStatus()) || PlanStatusEnum.isDelay(plan.getPlanStatus()));

		Wrapper<PlanPicture> planPictureWrapper = new EntityWrapper<>();
		planPictureWrapper.eq("plan_id", plan.getId());
		List<PlanPicture> planPictures = planPictureService.selectList(planPictureWrapper);
		if (planPictures != null && planPictures.size() > 0) {
			String[] planPictureArr = new String[planPictures.size()];
			int index = 0;
			for (PlanPicture planPicture : planPictures) {
				planPictureArr[index++] = planPicture.getPicUrl();
			}
			requestModel.setPlanPictures(planPictureArr);
		}

		Wrapper<PlanLabel> planLabelWrapper = new EntityWrapper<>();
		planLabelWrapper.eq("plan_id", plan.getId());
		List<PlanLabel> planLabels = planLabelService.selectList(planLabelWrapper);
		if (planLabels != null && planLabels.size() > 0) {
			String[] planLabelArr = new String[planLabels.size()];
			int index = 0;
			for (PlanLabel planLabel : planLabels) {
				planLabelArr[index++] = planLabel.getLabelName();
			}
			requestModel.setPlanLabelArr(planLabelArr);
		}

		return AjaxResult.success().put("plan", requestModel);
	}

	@ResponseBody
	@RequestMapping(value = { "/updatePlanSpeed" })
	public AjaxResult updatePlanSpeed(@RequestBody(required = true) PlanModel requestModel) {
		String token = requestModel.getToken();
		if (StringUtils.isBlank(token)) {
			return AjaxResult.error("请求失败，无效的数据 E1");
		}

		String userId = AesUtil.decryptStr(token);
		if (userId == null) {
			return AjaxResult.error("请求失败，无效的数据 E3");
		}

		User user = userService.selectById(new Long(userId));
		if (user == null) {
			return AjaxResult.error("请求失败，无效的数据 E4");
		}

		String planId = requestModel.getPlanId();
		if (StringUtils.isBlank(planId)) {
			return AjaxResult.error("请求失败，无效的数据 E5");
		}

		Plan plan = planService.selectById(planId);
		if (plan == null) {
			return AjaxResult.error("请求失败，无效的数据 E6");
		}

		String planSpeed = requestModel.getPlanSpeed();
		if (!NumberUtil.isInteger(planSpeed)) {
			return AjaxResult.error("请求失败，无效的数据 E7");
		}
		plan.setPlanSpeed(new Integer(planSpeed));

		if (plan.getPlanSpeed().intValue() == 100) {
			plan.setPlanStatus(PlanStatusEnum.Finish.code());
			plan.setFinishTime(DateUtil.date());
			plan.setUseTime(DateUtil.date().getTime() - plan.getCreateTime().getTime());
		} else {
			plan.setPlanStatus(PlanStatusEnum.HaveInHand.code());
		}

		return AjaxResult.success().put("res", planService.updateById(plan));
	}

	@ResponseBody
	@RequestMapping(value = { "/canclePlan" })
	public AjaxResult canclePlan(@RequestBody(required = true) PlanModel requestModel) {
		String token = requestModel.getToken();
		if (StringUtils.isBlank(token)) {
			return AjaxResult.error("请求失败，无效的数据 E1");
		}

		String userId = AesUtil.decryptStr(token);
		if (userId == null) {
			return AjaxResult.error("请求失败，无效的数据 E3");
		}

		User user = userService.selectById(new Long(userId));
		if (user == null) {
			return AjaxResult.error("请求失败，无效的数据 E4");
		}

		String planId = requestModel.getPlanId();
		if (StringUtils.isBlank(planId)) {
			return AjaxResult.error("请求失败，无效的数据 E5");
		}

		Plan plan = planService.selectById(planId);
		if (plan == null) {
			return AjaxResult.error("请求失败，无效的数据 E6");
		}

		plan.setCancleTime(DateUtil.date());
		plan.setPlanStatus(PlanStatusEnum.Cancel.code());

		return AjaxResult.success().put("res", planService.updateById(plan));
	}
}
